﻿/**************************************************************
*作者：Leon
*创建时间：2022/4/5 15:32:10
**************************************************************/
using Microsoft.Toolkit.Mvvm.Messaging;
using Microsoft.Toolkit.Mvvm.Messaging.Messages;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;

namespace Lad.DrawProject.Controls;

public partial class BaseCanvas:Canvas
{
    private IBaseCanvasViewModel ViewModel
    {
        get
        {
            if (DataContext is IBaseCanvasViewModel model)
                return model;
            throw new NotImplementedException("DesignerCanvas.DataContext is not IDiagramViewModel ");
        }
    }

    private IDiagramServiceProvider Service { get { return DiagramServicesProvider.Instance; } }
    private Point? rubberbandSelectionStartPoint = null;
    private ScrollViewer? scrollViewer;
    private ScrollViewer? ScrollView{ get {
            if (scrollViewer == null)
            {
                Visual? root = VisualTreeHelper.GetParent(this) as Visual;
                while (root != null && root is not ScrollViewer)
                    root = VisualTreeHelper.GetParent(root) as Visual;
                scrollViewer=root as ScrollViewer;
            }
            return scrollViewer;
        } }
    /// <summary>
    /// 鼠标按下
    /// </summary>
    /// <param name="e"></param>
    protected override void OnMouseDown(MouseButtonEventArgs e)
    {
        base.OnMouseDown(e);
        Zoom(e);

        //格式化
        if (Service.CursorMode == CursorMode.Format)
        {
            if (e.OriginalSource is FrameworkElement element && element.DataContext is SelectableItemViewModelBase target)
            {
                Format(ViewModel.SelectedItems.FirstOrDefault(), target);
                return;
            }

            ExitCursor();
        }
        else if (Service.CursorMode == CursorMode.Move)
        {
            ExitCursor();
            return;
        }

        if (e.LeftButton == MouseButtonState.Pressed)
        {
            //if we are source of event, we are rubberband selecting
            if (e.Source == this)
            {
                // in case that this click is the start for a 
                // drag operation we cache the start point
                rubberbandSelectionStartPoint = e.GetPosition(this);

                if (this.DataContext is IBaseCanvasViewModel vm && (!(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))))
                {
                    vm.ClearSelectedItemsCommand.Execute(null);
                }
                e.Handled = true;
                this.Focus();//捕获鼠标角点，否则无法触发键盘事件
            }
        }
    }

    /// <summary>
    /// 鼠标移动
    /// 1、设置viewModel.CurrentPoint；获取鼠标相对于显示器的位置
    /// 2、获取鼠标位置的颜色，并设置 viewModel.CurrentColor
    /// 3、如果是移动更新当前选择DesignerItemViewModelBase的位置为currentPoint
    /// </summary>
    /// <param name="e"></param>
    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);

        Point currentPoint = e.GetPosition(this);
        Service.CurrentPoint = currentPoint;
        //var point = CursorPointManager.GetCursorPosition();
        //Service.CurrentColor = ColorPickerManager.GetColor(point.X, point.Y);

        if (Service.CursorMode == CursorMode.Move)
        {
            ViewModel.SelectedItems.OfType<DesignerItemViewModelBase>().ToList().ForEach(p =>
            {
                p.Left = currentPoint.X;
                p.Top = currentPoint.Y;
            });
            return;
        }



        // if mouse button is not pressed we have no drag operation, ...
        if (e.LeftButton != MouseButtonState.Pressed && Service.DrawMode != DrawMode.DirectLine)
            rubberbandSelectionStartPoint = null;

        // ... but if mouse button is pressed and start
        // point value is set we do have one
        if (this.rubberbandSelectionStartPoint.HasValue)
        {
            // create rubberband adorner
            AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);
            if (adornerLayer != null)
            {
                RubberbandAdorner adorner = new(this, rubberbandSelectionStartPoint);
                if (adorner != null)
                    adornerLayer.Add(adorner);
            }
        }

        e.Handled = true;
    }

    /// <summary>
    /// 鼠标抬起
    /// 广播鼠标抬起的通知；刷新绘图模式
    /// </summary>
    /// <param name="e"></param>
    protected override void OnMouseUp(MouseButtonEventArgs e)
    {
        base.OnMouseUp(e);

        if (Service.DrawMode == DrawMode.DirectLine)
            return;

        WeakReferenceMessenger.Default
            .Send<ValueChangedMessage<bool>, string>(new(true), "DoneDrawingMessage");

        Service.ResetDrawMode();
    }

    /// <summary>
    /// 键盘按下上、下、左、右移动选中的对象
    /// </summary>
    /// <param name="e"></param>
    protected override void OnPreviewKeyDown(KeyEventArgs e)
    {
        base.OnPreviewKeyDown(e);

        if (e.Key == Key.Left)
        {
            if (ViewModel.SelectedItems != null)
            {
                foreach (var item in ViewModel.SelectedItems.OfType<DesignerItemViewModelBase>())
                {
                    item.Left -= 0.1;
                }
            }
        }
        else if (e.Key == Key.Right)
        {
            if (ViewModel.SelectedItems != null)
            {
                foreach (var item in ViewModel.SelectedItems.OfType<DesignerItemViewModelBase>())
                {
                    item.Left += 0.1;
                }
            }
        }
        else if (e.Key == Key.Up)
        {
            if (ViewModel.SelectedItems != null)
            {
                foreach (var item in ViewModel.SelectedItems.OfType<DesignerItemViewModelBase>())
                {
                    item.Top -= 0.1;
                }
            }
        }
        else if (e.Key == Key.Down)
        {
            if (ViewModel.SelectedItems != null)
            {
                foreach (var item in ViewModel.SelectedItems.OfType<DesignerItemViewModelBase>())
                {
                    item.Top += 0.1;
                }
            }
        }
 
    }

    protected override Size MeasureOverride(Size constraint)
    {

        Size size = new();


        foreach (UIElement? element in this.InternalChildren)
        {
            if (element == null) continue;

            double left = Canvas.GetLeft(element);
            double top = Canvas.GetTop(element);
            left = double.IsNaN(left) ? 0 : left;
            top = double.IsNaN(top) ? 0 : top;

            //measure desired size for each child
            element.Measure(constraint);

            Size desiredSize = element.DesiredSize;
            if (!double.IsNaN(desiredSize.Width) && !double.IsNaN(desiredSize.Height))
            {
                size.Width = Math.Max(size.Width, left + desiredSize.Width);
                size.Height = Math.Max(size.Height, top + desiredSize.Height);
            }
        }
        size.Width += 10;
        size.Height += 10;
        return size;
    }
    protected override void OnRender(DrawingContext dc)
    {
        //base.OnRender(dc);
        var rect = new Rect(0, 0, RenderSize.Width, RenderSize.Height);
        dc.DrawRectangle(Background, null, rect);
    }
    protected override void OnMouseWheel(MouseWheelEventArgs e)
    {
        base.OnMouseWheel(e);

        if (!Keyboard.IsKeyDown(Key.LeftCtrl) && !Keyboard.IsKeyDown(Key.RightCtrl))
        {
            return;
        }

        ViewModel.Zoom(e.Delta);

        e.Handled = true;
    }
}
